package top.kangert.kspider.executor.function.extension;

import top.kangert.kspider.annotation.Comment;
import top.kangert.kspider.annotation.Example;
import top.kangert.kspider.executor.FunctionExtension;
import top.kangert.kspider.util.ExtractUtils;

import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class ElementsFunctionExtension implements FunctionExtension {

    @Override
    public Class<?> support() {
        return Elements.class;
    }

    @Comment("根据 xpath 提取内容")
    @Example("${elementsVar.xpath('//title/text()')}")
    public static String xpath(Elements elements, String xpath) {
        return ExtractUtils.getValueByXPath(elements, xpath);
    }

    @Comment("根据 xpath 提取内容")
    @Example("${elementsVar.xpaths('//h2/text()')}")
    public static List<String> xpaths(Elements elements, String xpath) {
        return ExtractUtils.getValuesByXPath(elements, xpath);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regx('<title>(.*?)</title>')}")
    public static String regx(Elements elements, String regx) {
        return ExtractUtils.getFirstMatcher(elements.html(), regx, true);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regx('<title>(.*?)</title>',1)}")
    public static String regx(Elements elements, String regx, int groupIndex) {
        return ExtractUtils.getFirstMatcher(elements.html(), regx, groupIndex);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regx('<a href=\"(.*?)\">(.*?)</a>',[1,2])}")
    public static List<String> regx(Elements elements, String regx, List<Integer> groups) {
        return ExtractUtils.getFirstMatcher(elements.html(), regx, groups);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regxs('<h2>(.*?)</h2>')}")
    public static List<String> regxs(Elements elements, String regx) {
        return ExtractUtils.getMatchers(elements.html(), regx, true);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regxs('<h2>(.*?)</h2>',1)}")
    public static List<String> regxs(Elements elements, String regx, int groupIndex) {
        return ExtractUtils.getMatchers(elements.html(), regx, groupIndex);
    }

    @Comment("根据正则表达式提取内容")
    @Example("${elementsVar.regxs('<a href=\"(.*?)\">(.*?)</a>',[1,2])}")
    public static List<List<String>> regxs(Elements elements, String regx, List<Integer> groups) {
        return ExtractUtils.getMatchers(elements.html(), regx, groups);
    }

    @Comment("根据 css 选择器提取内容")
    @Example("${elementsVar.selector('div > a')}")
    public static Element selector(Elements elements, String selector) {
        Elements foundElements = elements.select(selector);
        if (foundElements.size() > 0) {
            return foundElements.get(0);
        }
        return null;
    }

    @Comment("返回所有 attr")
    @Example("${elementsVar.attrs('href')}")
    public static List<String> attrs(Elements elements, String key) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.attr(key));
        }
        return list;
    }

    @Comment("返回所有 value")
    @Example("${elementsVar.vals()}")
    public static List<String> vals(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.val());
        }
        return list;
    }

    @Comment("返回所有 text")
    @Example("${elementsVar.texts()}")
    public static List<String> texts(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.text());
        }
        return list;
    }

    @Comment("返回所有 html")
    @Example("${elementsVar.htmls()}")
    public static List<String> htmls(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.html());
        }
        return list;
    }

    @Comment("返回所有 outerHtml")
    @Example("${elementsVar.outerHtmls()}")
    public static List<String> outerHtmls(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.outerHtml());
        }
        return list;
    }

    @Comment("返回所有 ownTexts")
    @Example("${elementsVar.ownTexts()}")
    public static List<String> ownTexts(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.ownText());
        }
        return list;
    }

    @Comment("返回所有 wholeText")
    @Example("${elementsVar.wholeTexts()}")
    public static List<String> wholeTexts(Elements elements) {
        List<String> list = new ArrayList<>(elements.size());
        for (Element element : elements) {
            list.add(element.wholeText());
        }
        return list;
    }

    @Comment("根据 css 选择器提取内容")
    @Example("${elementsVar.selectors('div > a')}")
    public static Elements selectors(Elements elements, String selector) {
        return elements.select(selector);
    }

    @Comment("获取上级节点")
    @Example("${elementsVar.parents()}")
    public static Elements parents(Elements elements) {
        return elements.parents();
    }

}
